package com.gitee.deament.tianyancha.core.aop;

import com.gitee.deament.tianyancha.annotation.ParamRequire;
import com.gitee.deament.tianyancha.core.TianyanchaResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;

import java.lang.reflect.Field;

/**
 * 参数校验拦截
 *
 * @author Deament
 */
@Aspect
public class ParamCheckAop implements Ordered {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Before("execution(* com.gitee.deament.tianyancha.core.base.BaseRequest.get(..))")
    public void before() {
        logger.debug("前置");
    }

    @After("execution(* com.gitee.deament.tianyancha.core.base.BaseRequest.get(..))")
    public void after() {
        logger.debug("通知方法返回或者异常后调用");
    }

    @AfterReturning("execution(* com.gitee.deament.tianyancha.core.base.BaseRequest.get(..))")
    public void afterReturning() {
        logger.debug("通知方法完成后调用");
    }

    @AfterThrowing("execution(* com.gitee.deament.tianyancha.core.base.BaseRequest.get(..))")
    public void afterThrowing() {
        logger.debug("通知方法异常后调用");
    }

    @Around("execution(* com.gitee.deament.tianyancha.core.base.BaseRequest.get(..))")
    public TianyanchaResult around(ProceedingJoinPoint pj) {
        try {
            Object[] args = pj.getArgs();
            Object arg = args[0];
            if (arg == null) {
                TianyanchaResult nullResult = new TianyanchaResult();
                nullResult.setError_code(500);
                nullResult.setReason("被拦截：参数为空");
                return nullResult;
            }
            Field[] fields = arg.getClass().getDeclaredFields();
            int emptyCount = 0;
            for (Field field : fields) {
                field.setAccessible(true);
                ParamRequire paramRequire = field.getAnnotation(ParamRequire.class);
                boolean require = paramRequire.require();
                if (require && field.get(arg) == null) {
                    TianyanchaResult nullResult = new TianyanchaResult();
                    nullResult.setError_code(400);
                    nullResult.setReason("被拦截：" + field.getName() + "是必填项");
                    return nullResult;
                }

                //pageSize pageNum 分页参数不能小于0
                if (field.get(arg) != null && field.getName().equals("pageSize") && field.getLong(arg) < 1) {

                    TianyanchaResult nullResult = new TianyanchaResult();
                    nullResult.setError_code(400);
                    nullResult.setReason("被拦截：分页个数不合法");
                    return nullResult;
                }
                if (field.get(arg) != null && field.getName().equals("pageNum") && field.getLong(arg) < 1) {
                    TianyanchaResult nullResult = new TianyanchaResult();
                    nullResult.setError_code(400);
                    nullResult.setReason("被拦截：第几页设置不合法");
                    return nullResult;
                }

                if (field.get(arg) == null) {
                    //什么参数都没有值
                    emptyCount++;
                }
            }
            if (emptyCount == fields.length) {
                TianyanchaResult nullResult = new TianyanchaResult();
                nullResult.setError_code(400);
                nullResult.setReason("被拦截：没有任何参数，请重新输入");
                return nullResult;
            }


            return (TianyanchaResult) pj.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return new TianyanchaResult();
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}
